package com.zgw.fireline.design.common;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.eclipse.core.internal.resources.Folder;
import org.eclipse.core.internal.resources.Resource;
import org.eclipse.core.internal.resources.Workspace;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.core.JavaProject;
import org.eclipse.jdt.internal.corext.buildpath.CPJavaProject;
import org.eclipse.jdt.internal.corext.buildpath.ClasspathModifier;
import org.eclipse.jdt.internal.ui.util.BusyIndicatorRunnableContext;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.BuildPathsBlock;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.CPListElement;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.internal.WorkbenchPlugin;

public class ProjectUtil {
	/**
	 * 每个工程对应的输出路径
	 * */
	private Map<String, File> outPutMap = new HashMap<String, File>();
	private IResourceChangeListener outputListener;

	/**
	 * 初始化工程的类路径 与参数中指定的 classPaths 同步
	 * 
	 * */
	@SuppressWarnings({ "restriction", "rawtypes", "unchecked" })
	public void iniClassPath(URL[] classPaths, String projectName)
			throws Exception {
		Path lib = new Path("/" + projectName + "/lib/");
		Workspace w = (Workspace) ResourcesPlugin.getWorkspace();
		IPath[] paths = synLibs(classPaths, projectName);
		boolean isChange = false;
		IProject project = (IProject) w.newResource(
				new Path("/" + projectName), IResource.PROJECT);
		IJavaProject javaProject = JavaCore.create(project);
		CPJavaProject cpjava = CPJavaProject.createFromExisting(javaProject);
		List oldEntries = new ArrayList();
		oldEntries.addAll(cpjava.getCPListElements());
		ClasspathModifier.addExternalJars(paths, cpjava);
		List newEntries = new ArrayList();
		newEntries.addAll(cpjava.getCPListElements());

		// 移除 classPaths 中不存在的
		boolean remove = true;
		for (Object obj : cpjava.getCPListElements()) {
			remove = true;
			CPListElement e = (CPListElement) obj;
			IPath old_path = e.getClasspathEntry().getPath();
			if (!lib.isPrefixOf(old_path)) {
				continue;
			}
			for (IPath p : paths) {
				if (old_path.equals(p)) {
					remove = false;
					break;
				}
			}
			if (remove) {
				newEntries.remove(obj);
				isChange = true;
			}
		}
		// 通过比较newEntries oldEntries 得出ClassPath是否已改变
		if (newEntries.size() != oldEntries.size() || isChange) {
			ClasspathModifier.commitClassPath(newEntries, javaProject, null);
		}
	}

	private static IPath[] synLibs(URL[] classPaths, String projectName)
			throws Exception {
		Workspace w = (Workspace) ResourcesPlugin.getWorkspace();
		Path lib = new Path("/" + projectName + "/lib/");
		Folder libFolder = (Folder) w.newResource(lib, Resource.FOLDER);
		if (!libFolder.exists()) {
			libFolder.create(true, true, null);
		}
		IPath[] paths = new IPath[classPaths.length];
		int i = 0;
		boolean isChange = false;
		File synFile = new File(Platform.getLocation().toString()
				+ lib.toString(), ".syn.properties");
		if (!synFile.exists()) {
			synFile.createNewFile();
		}
		Properties synPro = new Properties();
		FileInputStream in = new FileInputStream(synFile);
		try {
			synPro.load(in);
		} finally {
			in.close();
		}
		for (URL url : classPaths) {
			long s_last = url.openConnection().getLastModified();

			String fileName = url.toString().substring(
					url.toString().lastIndexOf("/") + 1);
			File file = new File(Platform.getLocation().toString()
					+ lib.toString() + fileName);
			String t_last = "-1";
			if (file.exists()) {
				t_last = synPro.getProperty(file.getName());
			}
			if (!String.valueOf(s_last).equals(t_last)) {
				InputStream stream = url.openStream();
				try {
					FileUtil.copyFileBufferStream(stream, file);
					synPro.setProperty(file.getName(), s_last + "");
					isChange = true;
				} finally {
					stream.close();
				}
			}
			paths[i++] = new Path(lib.toString() + fileName);
		}
		if (isChange) {
			w.getRefreshManager().refresh(w.newResource(lib, IResource.FOLDER));
			FileOutputStream OUT = new FileOutputStream(synFile);
			try {
				synPro.store(OUT, "");
			} finally {
				OUT.close();
			}
		}
		return paths;
	}

	@SuppressWarnings("restriction")
	public void setOutPut(String projectId, File outPut) {
		outPutMap.put(projectId, outPut);
		if (outputListener == null) {
			outputListener = new IResourceChangeListener() {
				Thread synTask;

				public void resourceChanged(final IResourceChangeEvent event) {
					if (synTask != null && synTask.isAlive()) {
						return;
					}
					final Workspace workspace = (Workspace) ResourcesPlugin
							.getWorkspace();
					synTask = new Thread(new Runnable() {
						public void run() {
							while (workspace.getBuildManager()
									.isAutobuildBuildPending()) {
								try {
									Thread.currentThread().sleep(1000);
								} catch (InterruptedException e) {
									e.printStackTrace();
								}
							}
							System.out.println("构建完毕");
							for (Map.Entry<String, File> entry : outPutMap
									.entrySet()) {
								IPath binPath = new Path("/" + entry.getKey()
										+ "/bin");
								IResourceDelta bin = event.getDelta()
										.findMember(binPath);
								if (bin != null) {
									synFile(bin, new File(entry.getValue(),
											"bin"));
								}
								// IPath srcPath = new Path("/" + entry.getKey()
								// + "/src");
								// IResourceDelta src = event.getDelta()
								// .findMember(srcPath);
								// if (src != null) {
								// synFile(src, new File(entry.getValue(),
								// "src"));
								// }
							}
						}
					});
					synTask.start();
				}
			};
			Workspace WORKSPACE = (Workspace) ResourcesPlugin.getWorkspace();
			WORKSPACE.addResourceChangeListener(outputListener,
					IResourceChangeEvent.POST_BUILD);
		}

	}

	private void synFile(IResourceDelta data, File target) {
		File s, t;
		boolean result = true;
		for (IResourceDelta c : data.getAffectedChildren()) {
			s = new File(Platform.getLocation().toString()
					+ c.getFullPath().toString());
			t = new File(target, s.getName());
			if (t.exists()) {
				if (!s.exists() || (t.isDirectory() != s.isDirectory())) {
					if (result = FileUtil.clear(t)) {
						System.out.println("删除路径:" + t.toString());
					} else if (Display.getCurrent() != null) {
						WorkbenchPlugin.log("删除文件失败:" + t.toString());
					}
				}
			}
			if (s.exists() && s.isDirectory()) {
				t.mkdir();
				if (c.getAffectedChildren().length > 0)
					synFile(c, t);
			} else if (s.exists() && s.isFile()) {
				try {
					FileUtil.copyFileBufferStream(s, t);
				} catch (IOException e) {
					WorkbenchPlugin.log("同步文件失败:" + t.toString() + "  "
							+ e.getMessage());
					result = false;
				}
			}
		}
	}

	public void createJavaProject(String projectName) throws CoreException {
		final Workspace WORKSPACE = (Workspace) ResourcesPlugin.getWorkspace();
		IProject project = (IProject) WORKSPACE.newResource(new Path(
				projectName), IResource.PROJECT);
		Assert.isTrue(!project.exists(), projectName + "已存在");
		JavaCore core;
		// JavaProjectWizard w;
		JavaProject p;
		BuildPathsBlock.createProject(project, null, null);
		BuildPathsBlock.addJavaNature(project, null);
		IJavaProject javaProject = JavaCore.create(project);
		IPath outPut = BuildPathsBlock.getDefaultOutputLocation(javaProject);
		BuildPathsBlock fBuildPathsBlock = new BuildPathsBlock(
				new BusyIndicatorRunnableContext(), null, 0, false, null);
		fBuildPathsBlock.init(javaProject, null, null);
		fBuildPathsBlock.configureJavaProject(null, null);
		IFolder folder = (IFolder) WORKSPACE.newResource(new Path(projectName
				+ "/lib"), IResource.FOLDER);
		folder.create(true, true, null);
	}
}
